// 通用的抽取到这里面
import 'package:flutter/material.dart';
import 'package:net/navigator/bottom_navigator.dart';
import 'package:net/page/dark_mode_page.dart';
import 'package:net/page/home.dart';
import 'package:net/page/login_page.dart';
import 'package:net/page/notice_page.dart';
import 'package:net/page/registration_page.dart';
import 'package:net/page/video_detail.dart';
import 'package:url_launcher/url_launcher.dart';

// 创建页面
pageWrap(Widget child) {
  // 第一个参数保证唯一
  return MaterialPage(key: ValueKey(child.hashCode), child: child);
}

// 自定义路由封装 ，路由状态
enum RouteStatus {
  login,
  registration,
  home,
  detail,
  notice,
  darkModePage,
  unknown
}

// 获取page对应的RouteStatus

RouteStatus getStatus(MaterialPage page) {
  if (page.child is HLogin) {
    return RouteStatus.login;
  } else if (page.child is HRegis) {
    return RouteStatus.registration;
  } else if (page.child is BottomNavigator) {
    return RouteStatus.home;
  } else if (page.child is VideoDetailPage) {
    return RouteStatus.detail;
  } else if (page.child is NoticePage) {
    return RouteStatus.notice;
  } else if (page.child is DarkModePage) {
    return RouteStatus.darkModePage;
  } else {
    return RouteStatus.unknown;
  }
}

//状态对应的页面 ---路由信息
class RouteStatusInfo {
  final RouteStatus routeStatus;
  final Widget page;
  RouteStatusInfo(this.routeStatus, this.page);
}

//获取routeStatus在页面栈pages中的位置
int getPageIndex(List<MaterialPage> pages, RouteStatus routeStatus) {
  for (int i = 0; i < pages.length; i++) {
    MaterialPage page = pages[i];
    if (getStatus(page) == routeStatus) {
      return i;
    }
  }
  return -1;
}

// 监听路由页面跳转---处理不再通过回调函数那种方式跳转-封装
// 感知当前页面是否压后台
class HiNavigator extends _RouteJumpListener {
  static HiNavigator _instance;
  RouteJumpListener _routeJump;
  List<RouteChangeListener> _listeners = [];
  RouteStatusInfo _current;

  HiNavigator._();

  static HiNavigator geInstance() {
    //单例
    if (_instance == null) {
      _instance = HiNavigator._();
    }
    return _instance;
  }

  RouteStatusInfo getCurrent() {
    return _current;
  }

  //注册路由跳转逻辑---目的就是获取routeJumpListener然后供HiNavigator里面使用
  void registerRouteJump(RouteJumpListener routeJumpListener) {
    this._routeJump = routeJumpListener;
  }

  @override //实现抽象方法：就是实现通过这个·跳转页面传参
  void onJumpTo(RouteStatus routeStatus, {Map args}) {
    _routeJump.onJumpTo(routeStatus, args: args);
  }

  // 监听路由页面跳转
  void addListener(RouteChangeListener listener) {
    if (!_listeners.contains(listener)) {
      _listeners.add(listener);
    }
  }

  // 移除监听
  void removeListener(RouteChangeListener listener) {
    _listeners.remove(listener);
  }

  // 通知路由页面变化
  void notify(List<MaterialPage> currentPages, List<MaterialPage> prePages) {
    if (currentPages == prePages) return;
    var current =
        RouteStatusInfo(getStatus(currentPages.last), currentPages.last.child);
    _notify(current);
  }

  void _notify(RouteStatusInfo current) {
    // 监听底部导航栏
    if (current.page is BottomNavigator && _bottomTab != null) {
      //如果打开的是首页，则明确到首页具体的tab
      current = _bottomTab;
    }

    // 监听到是pre从哪个页面来的  以及当前页面
    // print('hi_navigator:current:${current.page}');
    // print('hi_navigator:pre:${_current?.page}');
    _listeners.forEach((listener) {
      listener(current, _current);
    });
    _current = current;
  }

  // 首页底部tab
  RouteStatusInfo _bottomTab;
  //首页底部tab切换监听
  void onBottomTabChange(int index, Widget page) {
    _bottomTab = RouteStatusInfo(RouteStatus.home, page);
    _notify(_bottomTab);
  }

// 借助url_launcher实现H5跳转
  Future<bool> openH5(String url) async {
    var result = await canLaunch(url);
    if (result) {
      return await launch(url);
    } else {
      return Future.value(false);
    }
  }
}

//声明抽象类来监听跳转
abstract class _RouteJumpListener {
  //定义子类必须实现的跳转方法,参数1是跳转路由,参数2是map参数
  void onJumpTo(RouteStatus routeStatus, {Map args});
}

//用typeof定义某个类型
typedef OnJumpTo = void Function(RouteStatus routeStatus, {Map args});

//要想HiNavigator拥有跳转功能，但是他本身又没有 ，就定义一个，然后持有它的实例
//定义路由跳转逻辑要实现的跳转功能
class RouteJumpListener {
  final OnJumpTo onJumpTo;
//里面有一个非必填的onJumpTo方法
  RouteJumpListener({this.onJumpTo});
}

// 监听是否被压后台
typedef RouteChangeListener(RouteStatusInfo current, RouteStatusInfo pre);

/*
增加页面切换监听 进入离开页面(押后台监听)
 List<RouteChangeListener> _listeners = [];
   RouteStatusInfo _current;
 void addListener
 void removeListener
  notify
   _notify
*/

